Spring Boot不像Spring采用XML配置,而是使用Spring JavaConfig注解配置,配置方法更加简化。本文总结了Spring Boot的核心注解和常用注解。
1.核心注解@SpringBootApplication
@SpringBootApplication是Spring Boot的核心注解,通常用在项目的启动类上,申明让Spring Boot自动为程序进行必要的配置。其组合了以下三个注解:
- @SpringBootConfiguration 组合了@Configuration注解,等同于Spring的XML配置文件功能,将注解类中的Bean装配到Spring容器中。
- @EnableAutoConfiguration 打开自动配置的功能。会自动去maven中扫描项目依赖的每个starter中jar包下的META-INF/spring.factories文件,扫描文件中key为EnableAutoConfiguration的所有配置类,将在配置类中配置的Bean加入到IOC容器中。
- @ComponentScan 申明让Spring Boot扫描当前类(一般是启动类)所在包,找到所有组件类(Component、Controller、Service、Repository等),并将其装配到Spring IOC容器中,相当于加入到程序上下文(Spring中的applicationcontext.xml)。
@SpringBootApplication注解的源码:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication {
...
}
|
2.常用注解
(1)配置导入功能
- @Configuration 声明配置类,指出该类是Bean配置的信息源,相当于Spring的XML配置文件(中的
<beans></beans>
),一般注解在主类上。
- @Bean 相当于XML文件中的
<bean></bean>
,注解方法而非类,意思是产生一个Bean,并交给Spring管理,一般和@Configuration 结合使用:
@Configuration public class FusionOperationFactoryConfigure { @Bean public CommandLineRunner fusionOperationFactoryInitialization() { return (args -> { Reflections reflections = new Reflections("cn.ist.msplatform.channelservice.model.fusion"); for (Class clazz : reflections.getTypesAnnotatedWith(Fusion.class)) { Fusion fusion = (Fusion) clazz.getAnnotation(Fusion.class); FusionOperationFactory.register(fusion.operation(), clazz); } }); } }
|
- @Import 用来在当前配置类中导入其他配置类。在实际编码过程中,我们通常会将所需要的Bean分门别类地在不同的@Configuration类中进行声明配置,而不是写一个超级大的配置类来管理所有的SpringBean。有点类似于我们在Spring XML配置时写好几个文件比如application-context-dao.xml,application-context-service.xml之类的。使用@Import注解在不同的场景组合不同的配置类,该注解可以将其它@Configuration导入到当前的配置中。比如:
@Configuration @Import({ SpringConfig1.class, SpringConfig2.class }) public class JavaConfigImport { }
|
- @ImportResource 与@Import做的事情相似,区别在于用来导入XML配置文件而非@Configuration配置类。比如:
@Configuration @ImportResource("classptah: /application-context-*.xml") public class JavaConfigImportResource { }
|
- @Autowired 自动导入依赖的bean,byType按类型装配方式,把配置好的Bean拿来用,完成对象自动装配的工作。当加上(required = false),就算找不到Bean也不报错。
- @Resource(name = “name”, type = “type”) 与@Autowired干同样的事(适用于当同类型的Bean不止一个,需要借助name来指明要依赖的Bean的情况),没有括号内容的话默认byName按名称装配方式。Note:使用@Autowired+@Qualifier可以达到和使用@Resource一样的效果:
@Configuration @Slf4j public class KafkaConfigure { @Bean public KafkaProducer<String, String> kafkaProducer(@Value("${custom.kafka.url}") String url) { }
@Bean public KafkaConsumer<String, String> channelKafkaConsumer(@Value("${custom.kafka.url}") String url) { }
@Bean public KafkaConsumer<String, String> logKafkaConsumer(@Value("${custom.kafka.url}") String url) { } }
|
@Component public class KafkaConsumerSingleton { @Autowired @Qualifier("channelKafkaConsumer") private KafkaConsumer<String, String> channelKafkaConsumer; }
|
- @Inject 等价于默认的@Autowired,没有required属性。
(2)业务层功能
- @Component 泛指组件,当组件不好归类时,就用这个应付一下。
- @Controller注解控制器类,在Spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层)。一般在这个注解类中,通常方法需要配合注解@RequestMapping。
- @RestController是@ResponseBody和@Controller的合集。
- @Service 注解service层的组件。
- @Repository 注解数据访问组件。
- @RequestMapping 提供路由信息,负责URL到Controller中具体函数的映射。
- @RequestBody 表示该方法的返回结果直接写入HTTP response body中。
- @Value 注入application.properties或application.yml配置的属性的值。
(3)全局异常处理
- @ControllerAdvice 内部包含了@Component注解,因此可以被扫描到,注解在类上,统一处理异常。
- @ExceptionHandler 注解在方法上面,表示遇到这个异常就执行这个方法,和@Controller配合使用:
@ControllerAdvice @Slf4j public class GlobalExceptionHandler { @ExceptionHandler() @ResponseBody ResponseEntity handle(ObjectNotFoundException e) { return generateFailResponseEntity(ResultCode.OBJECT_NOT_FOUND, HttpStatus.NOT_FOUND, e.getMessage()); }
@ExceptionHandler() @ResponseBody ResponseEntity handle(ServiceException e) { Result result = ResultUtil.failure(e.resultCode); return new ResponseEntity(result, HttpStatus.OK); }
@ExceptionHandler() @ResponseBody ResponseEntity handle(UnImplementedFeatureException e) { return generateFailResponseEntity(ResultCode.UNIMPLEMENT_FEATURE, HttpStatus.OK, e.getMessage()); }
@ExceptionHandler() @ResponseBody ResponseEntity handle(RuntimeException e) { log.error("", e); Result result = ResultUtil.failure(e.getMessage(), ResultCode.RUN_TIME_EXCEPTION.getCode()); return new ResponseEntity(result, HttpStatus.OK); }
private ResponseEntity generateFailResponseEntity(ResultCode resultCode, HttpStatus ok, String... message) { String unformattedMessage = resultCode.getMessage(); int code = resultCode.getCode(); Result result = ResultUtil.failure(String.format(unformattedMessage, message), code); return new ResponseEntity(result, ok); }
}
|